許多開發者勢必會遇到一種狀況,就是在上線前勢必會先放到測試主機進行測試,我們稱之開發環境(Develop Environment,但每次都要修改組態檔(Config file)內部的DB連線資訊、配置檔內容,今天小編就依照Spring所預設的區分測試環境的設定檔,依照不同的環境可透過命令參數進行切換,這樣開發者就可依照不同環境自動觸發不同的組態檔,今日小編所提供的範例切分三種環境,區分為DEV、UAT及PROD環境,小編僅提供設定方法進行介紹,主要為了讓各位開發者離CI/CD會越離越近,現在就開始準備切割你的環境囉!
在每個專案都會預設一個application.properties或application.yml,故小編僅針對application.properties進行設計,此時專案的預設profile key為default,故Spring提供一項配置命令spring.profiles.active進行設置環境配置檔索引名稱,其相關聯的配置檔須遵循命名原則,故原生在通過部署的時候,可以通過指令java -jar XXX.jar --spring.profiles.active=dev進行組態檔串接,但小編覺得這樣太麻煩,如果沒帶預設環境參數,小編希望自動配置預設,故小編重新調整以下方法與Spring 原生環境配置對接,命名規則如下:
application-{profile}.properties
當我們切割出三項設定後,分別在內部放置環境屬性參數(sea.food.system.environment),當系統啟動時我們可得知目前所配置的參數為哪個設定檔,相關檔名配置如下(詳細資訊請看範例程式碼):
application name | sea.food.system.environment |
---|---|
application-dev.properties | Sea Food Development ENV |
application-staging.properties | Sea Food Staging ENV |
application-prod.properties | Sea Food Production ENV |
由於此環境參數最後通過Map集合中的springProfile key進行替換,故我們須在預設的application.properties組態檔中加上取代環境變數的參數,及加上替換的方法在build.gradle中,小編較少使用maven,但一樣也是透過pom.xml進行配置profiles參數,可以進行參考,相關設定如下:
application.properties setting profiles parameter
spring.profiles.active=@springProfile@
...
...
加入以下取代參數方法在build.gradle 中,以便若無配置系統環境參數依舊會吃預設的profile
def seaFoodSpringProfile = System.getProperty("profile") ?: "dev"
println('Build Sea Food System PROFILE : ' + seaFoodSpringProfile)
bootRun {
systemProperty 'spring.profiles.active', "${seaFoodSpringProfile}"
}
processResources {
filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [
springProfile: seaFoodSpringProfile
]
}
通過以上配置方式,我們就可以順利的將Spring的環境參數概念優化到對應的專案自動化構建工具中囉。
小編提供以下測試指令及結果提供各位開發者作參考。
Run dev/stag/prod environment application without JAR file
1. gradle bootRun -D profile=dev
2. gradle bootRun -D profile=stag
3. gradle bootRun -D profile=prod
Result sample
01:27:48.269 INFO 34931 --- [ main] sw.spring.sample.config.SeaFooConfig : *******************************************************
01:27:48.270 INFO 34931 --- [ main] sw.spring.sample.config.SeaFooConfig : *** Sync boot profile : [Sea Food Development ENV] ***
01:27:48.271 INFO 34931 --- [ main] sw.spring.sample.config.SeaFooConfig : *******************************************************
Build dev/stag/prod environment JAR boot file without test
1. gradle -Dprofile=dev clean build -x test
2. gradle -Dprofile=stag clean build -x test
3. gradle -Dprofile=prod clean build -x test
Build Jar Result sample
> Configure project :
Build Sea Food System PROFILE : prod
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.3/userguide/command_line_interface.html#sec:command_line_warnings
BUILD SUCCESSFUL in 4s
6 actionable tasks: 6 executed
當系統啟動後,會透過擴展的BaseParamFilterReader類別中read()方法,將所有環境變數檔名稱存入org.apache.tools.ant.filters.ReplaceTokens#tokens物件中(HashTable型態物件),此時我們透過命令提示字元進行替換環境參數,命令如下:
1. gradle -Dprofile=dev
2. gradle -Dprofile=stag
3. gradle -Dprofile=dev
透過Gradle進行傳遞參數至org.apache.tools.ant.filters.ReplaceTokens中名為tokens參數進行過濾取得其對應配置檔,其參數是一種HashTable型態物件,裡面存取專案資源中所有環境變數檔,並透過繼承之ChainableReader介面中的chain()方法進行過濾參數及取得對應環境變數設定檔,若找不到則都取用default的環境變數(application.properties)。
圖一、Spring 環境變數替換流程圖
JVM 設備監測環境資訊
使用 spring.profiles.active 及 @profile 注解 动态化配置内部及外部配置
gradle打包spring boot的测试、正式war、jar包